@using Nethereum.Wallet.UI.Components.Services
@using Nethereum.Wallet.UI.Components.SendTransaction
@using Nethereum.Wallet.UI.Components.SendTransaction.Models
@using Nethereum.Wallet.UI.Components.Blazor.SendTransaction
@using Nethereum.Wallet.UI.Components.Blazor.Shared
@using Nethereum.Wallet.UI.Components.Core.Localization
@using Nethereum.Wallet.UI.Components.Prompts
@using static Nethereum.Wallet.UI.Components.Prompts.DAppTransactionPromptLocalizer
@using MudBlazor
@implements IDisposable
@inject DAppTransactionPromptViewModel ViewModel
@inject IComponentLocalizer<DAppTransactionPromptViewModel> Localizer

<WalletFormLayout Title="@GetTitle()"
                  Subtitle="@GetSubtitle()"
                  Steps="@_steps"
                  CurrentStepIndex="@ViewModel.CurrentStep"
                  ExitText="@GetExitText()"
                  BackText="@Localizer.GetString(Keys.Back)"
                  ContinueText="@Localizer.GetString(Keys.Continue)"
                  PrimaryText="@GetPrimaryButtonText()"
                  ShowBack="@(ViewModel.CurrentStep > 0 && ViewModel.CurrentStep < 2)"
                  ShowContinue="@(ViewModel.CurrentStep == 0)"
                  ShowPrimary="@(ViewModel.CurrentStep == 1)"
                  ContinueDisabled="@(!ViewModel.CanProceedToNextStep)"
                  PrimaryDisabled="@(!ViewModel.CanApprove)"
                  OnExit="HandleExit"
                  OnBack="HandleBack"
                  OnContinue="HandleContinue"
                  OnPrimary="HandlePrimary">
    
    <ChildContent>
        @if (ViewModel.CurrentStep == 0)
        {
            <WalletFormSection Title="@Localizer.GetString(Keys.RequestDetails)">
                @if (PromptInfo != null && !string.IsNullOrEmpty(PromptInfo.DAppName))
                {
                    <WalletInfoCard Icon="@Icons.Material.Filled.Apps"
                                    Title="@PromptInfo.DAppName"
                                    Subtitle="@PromptInfo.Origin" />
                }
                
                
                
                <TransactionInput ViewModel="@ViewModel.Transaction"
                                Layout="TransactionInputLayout.Confirmation"
                                ShowTransactionDetails="true"
                                ShowDataDecoding="true"
                                RecipientReadOnly="true"
                                AmountReadOnly="true"
                                ShowGasConfiguration="false" />
                
                @if (!string.IsNullOrEmpty(PromptInfo?.WarningMessage))
                {
                    <MudAlert Severity="Severity.Warning" Class="mt-3">
                        @PromptInfo.WarningMessage
                    </MudAlert>
                }

                @if (!string.IsNullOrEmpty(ViewModel.ValidationError))
                {
                    <MudAlert Severity="Severity.Error" Class="mt-3">
                        @ViewModel.ValidationError
                    </MudAlert>
                }
            </WalletFormSection>
        }
        else if (ViewModel.CurrentStep == 1)
        {
            <WalletFormSection Title="@Localizer.GetString(Keys.GasConfiguration)">
                <TransactionInput ViewModel="@ViewModel.Transaction"
                                Layout="TransactionInputLayout.Confirmation"
                                ShowTransactionDetails="true"
                                ShowGasConfiguration="true"
                                ShowCostSummary="true"
                                RecipientReadOnly="true"
                                AmountReadOnly="true"
                                AllowGasModeSwitch="true" />
            </WalletFormSection>
            
            @if (!string.IsNullOrEmpty(ViewModel.ErrorMessage))
            {
                <MudAlert Severity="Severity.Error" Class="mt-3">
                    @ViewModel.ErrorMessage
                    @if (ViewModel.ShowRetry)
                    {
                        <MudButton Color="Color.Primary" 
                                  Variant="Variant.Text"
                                  Size="Size.Small"
                                  StartIcon="@Icons.Material.Filled.Refresh"
                                  OnClick="@(() => ViewModel.RetryTransactionCommand.Execute(null))"
                                  Class="ml-2">
                            @Localizer.GetString(Keys.Retry)
                        </MudButton>
                    }
                </MudAlert>
            }
        }
        else if (ViewModel.CurrentStep == 2)
        {
            @if (ViewModel.TransactionStatus != null)
            {
                <TransactionStatus ViewModel="@ViewModel.TransactionStatus" />
            }
            else
            {
                <MudStack AlignItems="AlignItems.Center" Justify="Justify.Center" Style="min-height: 200px;">
                    <MudProgressCircular Color="Color.Primary" Size="Size.Large" Indeterminate="true" />
                    <MudText Typo="Typo.body2" Color="Color.Secondary" Class="mt-3">
                        @Localizer.GetString(Keys.Processing)
                    </MudText>
                </MudStack>
            }

            @if (!string.IsNullOrEmpty(ViewModel.TransactionHash))
            {
                <MudAlert Severity="Severity.Success" Class="mt-3">
                    @Localizer.GetString(Keys.TransactionSent)
                </MudAlert>
            }
        }
    </ChildContent>
</WalletFormLayout>

@code {
    [Parameter] public PromptRequest PromptRequest { get; set; } = null!;
    [Parameter] public EventCallback<object?> OnApproved { get; set; }
    [Parameter] public EventCallback OnRejected { get; set; }
    
    private TransactionPromptInfo? PromptInfo => PromptRequest?.Data as TransactionPromptInfo;
    private readonly List<WalletFormStep> _steps = new();
    private string? _completedTransactionHash;
    
    protected override async Task OnInitializedAsync()
    {
        _steps.AddRange(new[]
        {
            new WalletFormStep { Label = Localizer.GetString(Keys.StepReview), Icon = Icons.Material.Filled.Preview },
            new WalletFormStep { Label = Localizer.GetString(Keys.StepConfirm), Icon = Icons.Material.Filled.Check },
            new WalletFormStep { Label = Localizer.GetString(Keys.StepStatus), Icon = Icons.Material.Filled.Done }
        });

        _completedTransactionHash = null;
        
        if (PromptInfo != null)
        {
            await ViewModel.InitializeAsync(PromptInfo);
            
            ViewModel.OnTransactionSent = async txHash =>
            {
                _completedTransactionHash = txHash;
                await InvokeAsync(StateHasChanged);
            };
            
            ViewModel.OnRejected = async () =>
            {
                await OnRejected.InvokeAsync();
            };
        }
    }
    
    private string GetTitle()
    {
        return ViewModel.CurrentStep switch
        {
            0 => Localizer.GetString(Keys.ReviewTransaction),
            1 => Localizer.GetString(Keys.ConfirmTransaction),
            2 => Localizer.GetString(Keys.TransactionStatus),
            _ => Localizer.GetString(Keys.TransactionRequest)
        };
    }
    
    private string GetSubtitle()
    {
        if (PromptInfo != null && !string.IsNullOrEmpty(PromptInfo.DAppName))
        {
            return Localizer.GetString(Keys.RequestFrom, PromptInfo.DAppName);
        }
        return "";
    }
    
    private string GetPrimaryButtonText()
    {
        return ViewModel.CurrentStep switch
        {
            1 => Localizer.GetString(Keys.SendTransaction),
            _ => Localizer.GetString(Keys.Continue)
        };
    }

    private string GetExitText()
    {
        if (!string.IsNullOrEmpty(_completedTransactionHash) || !string.IsNullOrEmpty(ViewModel.TransactionHash))
        {
            return Localizer.GetString(Keys.Close);
        }

        return Localizer.GetString(Keys.Reject);
    }
    
    private void HandleBack()
    {
        ViewModel.PreviousStepCommand.Execute(null);
    }
    
    private void HandleContinue()
    {
        ViewModel.NextStepCommand.Execute(null);
    }
    
    private async Task HandlePrimary()
    {
        if (ViewModel.CurrentStep == 1)
        {
            await ViewModel.ApproveAndSendTransactionCommand.ExecuteAsync(null);
        }
    }

    private async Task HandleExit()
    {
        if (!string.IsNullOrEmpty(_completedTransactionHash) || !string.IsNullOrEmpty(ViewModel.TransactionHash))
        {
            var hash = _completedTransactionHash ?? ViewModel.TransactionHash;
            _completedTransactionHash = null;
            await OnApproved.InvokeAsync(hash);
            return;
        }

        _completedTransactionHash = null;
        ViewModel.RejectTransactionCommand.Execute(null);
        await OnRejected.InvokeAsync();
    }

    private async Task HandleStatusExit()
    {
        await HandleExit();
    }

    public void Dispose()
    {
        ViewModel.OnTransactionSent = null;
        ViewModel.OnRejected = null;
        ViewModel.Dispose();
    }
}
